package com.ruoyi.framework.web.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SimpleQuery;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.entity.SysDeptEnterprise;
import com.ruoyi.common.core.domain.entity.SysEnterprise;
import com.ruoyi.common.core.domain.entity.SysUserEnterprise;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysStaff;
import com.ruoyi.system.domain.SysStaffDeptEnterpriseRel;
import com.ruoyi.system.mapper.SysEnterpriseMapper;
import com.ruoyi.system.service.ISysDeptEnterpriseService;
import com.ruoyi.system.service.ISysStaffDeptEnterpriseRelService;
import com.ruoyi.system.service.ISysStaffService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * 企业微信部门服务
 *
 * @author zhousiren
 * @since 2025/3/3 14:43
 */
@Component
@Slf4j
public class QywxDeptService {
    @Resource
    private SysEnterpriseMapper sysEnterpriseMapper;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysDeptEnterpriseService sysDeptEnterpriseService;

    @Autowired
    private ISysStaffService sysStaffService;

    @Autowired
    private ISysStaffDeptEnterpriseRelService sysStaffDeptEnterpriseRelService;

    /**
     * 获取企业微信部门列表
     *
     * @param
     */
    public List<Tree<Integer>> selectQywxDeptList(String corpId) {
        //获取登录用户的corpid
        if (StringUtils.isEmpty(corpId)) {
            corpId = getLoginUserCorpId();
        }
        try {
            List<SysDeptEnterprise> departments = sysDeptEnterpriseService.list(Wrappers.<SysDeptEnterprise>lambdaQuery().eq(SysDeptEnterprise::getCorpid, corpId));
            List<TreeNode<Integer>> treeNodes = new ArrayList<>();
            for (SysDeptEnterprise department : departments) {
                TreeNode<Integer> treeNode = new TreeNode<>();
                treeNode.setId(department.getId());
                treeNode.setParentId(department.getParentId());
                treeNode.setWeight(department.getWeight());
                treeNode.setName(department.getName());
                treeNodes.add(treeNode);
            }
            List<Tree<Integer>> trees = TreeUtil.build(treeNodes, 0);
            return trees;

        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 同步部门
     *
     * @param corpId
     */
    public String syncDeptData(String corpId) {
        if (StringUtils.isEmpty(corpId)) {
            corpId = getLoginUserCorpId();
        }
        SysEnterprise sysEnterprise = sysEnterpriseMapper.selectSysEnterpriseByCorpid(corpId);
        String accessToken = loginService.getEnterpriseAccessToken(corpId, sysEnterprise.getCorpsecret());
        String url = StringUtils.format("https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={}", accessToken);
        String result = HttpUtil.get(url);
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//忽略多余字段
            JsonNode rootNode = objectMapper.readTree(result);
            int errcode = rootNode.get("errcode").asInt();
            if (errcode == 0) {
                List<SysDeptEnterprise> departments = objectMapper.readValue(
                        rootNode.get("department").toString(),
                        new TypeReference<List<SysDeptEnterprise>>() {
                        }
                );
                if (CollUtil.isNotEmpty(departments)) {
                    //清空表再新增
                    sysDeptEnterpriseService.remove(null);
                    String finalCorpId = corpId;
                    departments.forEach(department -> department.setCorpid(finalCorpId));
                    sysDeptEnterpriseService.saveBatch(departments);
                    return "同步企业部门" + departments.size() + "条数据";
                } else {
                    return "微信企业部门数据为空";
                }
            } else {
                return rootNode.get("errmsg").asText();
            }
        } catch (Exception e) {
            log.error("同步部门数据错误", e);
            return "解析错误，请查看日志";
        }
    }

    /**
     * 根据部门id获取部门成员
     *
     * @param deptId
     */
    public List<User> getAllUserByDeptId(Integer deptId, String corpId) {
        //获取登录用户的corpid
        if (StringUtils.isEmpty(corpId)) {
            corpId = getLoginUserCorpId();
        }
        SysEnterprise sysEnterprise = sysEnterpriseMapper.selectSysEnterpriseByCorpid(corpId);
        String accessToken = loginService.getEnterpriseAccessToken(corpId, sysEnterprise.getCorpsecret());
        String url = StringUtils.format("https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token={}&department_id={}", accessToken, deptId);
        String result = HttpUtil.get(url);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        Integer errcodes = jsonObject.getInt("errcode");
        if (errcodes == 0) {
            List<User> users = jsonObject.getBeanList("userlist", User.class);
            return users;
        } else {
            throw new ServiceException(jsonObject.getStr("errmsg"));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean syncUserData(Integer deptId, String corpId) {
        List<User> users = getAllUserByDeptId(deptId, corpId);
        //企业微信的用户
        if (users == null) {
            return true;
        }
        HashSet<Long> staffSet = new HashSet<>(sysStaffDeptEnterpriseRelService.listObjs(Wrappers.<SysStaffDeptEnterpriseRel>lambdaQuery().eq(SysStaffDeptEnterpriseRel::getEnterpriseDeptId, deptId).select(SysStaffDeptEnterpriseRel::getStaffId), Convert::toLong));
        if (users.size() == 0) {
            sysStaffDeptEnterpriseRelService.remove(Wrappers.<SysStaffDeptEnterpriseRel>lambdaQuery().eq(SysStaffDeptEnterpriseRel::getEnterpriseDeptId, deptId));
            return true;
        }
        //当前系统部门下的员工id
        //key为企业微信id  value为系统员工id  差全部的员工
        Map<String, Long> map = SimpleQuery.map(Wrappers.<SysStaff>lambdaQuery().isNotNull(SysStaff::getEnterpriseUserId), SysStaff::getEnterpriseUserId, SysStaff::getStaffId);
        List<SysStaff> sysStaffList = new ArrayList<>();
        for (User user : users) {
            SysStaff sysStaff = new SysStaff();
            sysStaff.setName(user.getName());
            sysStaff.setSex("1".equals(user.getGander()) ? "0" : "1");
            sysStaff.setEnterpriseUserId(user.getUserid());
            sysStaff.setEmail(user.getEmail());
            sysStaff.setPhone(user.getMobile());
            //已存在就更新，不存在就新增
            if (map != null && map.containsKey(user.getUserid())) {
                sysStaff.setStaffId(map.get(user.getUserid()));
            }
            sysStaffList.add(sysStaff);
        }
        sysStaffService.saveOrUpdateBatch(sysStaffList);
        if (CollUtil.isNotEmpty(sysStaffList)) {
            List<SysStaffDeptEnterpriseRel> rels = new ArrayList<>();
            for (SysStaff sysStaff : sysStaffList) {
                if (!staffSet.contains(sysStaff.getStaffId())) {
                    SysStaffDeptEnterpriseRel sysStaffDeptEnterpriseRel = new SysStaffDeptEnterpriseRel();
                    sysStaffDeptEnterpriseRel.setEnterpriseDeptId(deptId);
                    sysStaffDeptEnterpriseRel.setStaffId(sysStaff.getStaffId());
                    rels.add(sysStaffDeptEnterpriseRel);
                }
            }
            sysStaffDeptEnterpriseRelService.saveBatch(rels);
        }
        return true;
    }

    private String getLoginUserCorpId() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUserEnterprise userEnterprise = loginUser.getUserEnterprise();
        if (userEnterprise == null) {
            throw new ServiceException("未获取到当前登录用户的企业微信信息");
        }
        return userEnterprise.getEnterpriseCorpId();
    }


    @Data
    public static class User {
        private String userid;
        private String name;
        private String gander;
        private String mobile;
        private String email;
        //private List<Integer> department;
    }
}

